
package com.gcloud.mesh.dcs.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.jeecg.common.constant.DictCode;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.online.config.exception.BusinessException;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gcloud.framework.db.PageResult;
import com.gcloud.mesh.asset.dao.CloudResourceConfigDao;
import com.gcloud.mesh.asset.dao.DatacenterDao;
import com.gcloud.mesh.asset.entity.CloudResourceConfigEntity;
import com.gcloud.mesh.asset.entity.DatacenterEntity;
import com.gcloud.mesh.dcs.dao.SchedulerAdviceDao;
import com.gcloud.mesh.dcs.dao.SchedulerJobDao;
import com.gcloud.mesh.dcs.entity.SchedulerAdviceEntity;
import com.gcloud.mesh.dcs.entity.SchedulerJobEntity;
import com.gcloud.mesh.dcs.enums.SchedulerAdviceStatus;
import com.gcloud.mesh.dcs.enums.SchedulerJobStatus;
import com.gcloud.mesh.header.exception.BaseException;
import com.gcloud.mesh.header.msg.dcs.AviableDatacenterMsg;
import com.gcloud.mesh.header.msg.dcs.PageInstanceMsg;
import com.gcloud.mesh.header.msg.dcs.PageSchedulerAdviceMsg;
import com.gcloud.mesh.header.msg.dcs.StartJobMsg;
import com.gcloud.mesh.header.vo.dcs.AppInstanceVo;
import com.gcloud.mesh.header.vo.dcs.DatacenterResourceVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerAdviceVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerOverview;
import com.gcloud.mesh.supplier.enums.SystemType;

import lombok.extern.slf4j.Slf4j;

@Service
//@CacheConfig(cacheNames = Module.COMPONENT)
@Slf4j
public class SchedulerAdviceService {

    @Autowired
    private SchedulerAdviceDao dao;
	@Autowired
	private SchedulerJobDao schedulerJobDao;
	@Autowired
	private DatacenterDao datacenterDao;
	
	@Autowired
	private AppService appService;
	

	@Autowired
	private SysDictMapper sysDictMapper;
	
	@Autowired
	private CloudResourceConfigDao cloudResourceConfigDao;

	public PageResult<SchedulerAdviceVo> advicePage(@Valid PageSchedulerAdviceMsg msg) {
		Map<String, String> dcNames = new HashMap<>();
		List<DatacenterEntity> dcs = datacenterDao.findAll();
		if (dcs != null) {
			for (DatacenterEntity dc : dcs) {
				dcNames.put(dc.getId(), dc.getName());
			}
		}
		PageResult<SchedulerAdviceVo> page =  dao.page(msg);
		List<SchedulerAdviceVo> list = page.getList();
		for(SchedulerAdviceVo vo : list) {
			vo.setDstDatacenterName(dcNames.get(vo.getDstDatacenterId()));
			vo.setSrcDatacenterName(dcNames.get(vo.getSrcDatacenterId()));
		}
		return page;
	}
	
	public void saveSchedulerAdvice(SchedulerAdviceEntity entity) {
		entity.setCreateTime(new Date());
		dao.save(entity);
	}
	
	public List<SchedulerAdviceEntity> listByAppId(String appId, String cloudResourceId, String instanceId, int model){
		Map<String, Object> param = new HashMap<>();
		param.put("app_id", appId);
		param.put("instance_id", instanceId);
		param.put("cloud_resource_id", cloudResourceId);
		param.put("scheduler_model", model);
		return dao.findByProperties(param);
	}
	
	
	public void savebatchAdvice(List<SchedulerAdviceEntity> entitys) {
		dao.saveBatch(entitys);
	}
	
	public List<SchedulerAdviceEntity> listReadyAdvice(Integer status){
		Map<String, Object> param = new HashMap<>();
		param.put("status", status);
		return dao.findByProperties(param);
	}
	
	public void moveOneAdviceToJob(Long adviceId) throws BusinessException {
		SchedulerAdviceEntity advice = dao.getById(adviceId);
		if(advice == null) {
			throw new BaseException(null, "该建议已失效，请刷新建议列表");
		}
		SchedulerJobEntity job = new SchedulerJobEntity();
		job.setAppId(advice.getAppId());
		job.setId(UUID.randomUUID().toString());
		job.setBeginTime(new Date());
		job.setCloudResourceId(advice.getCloudResourceId());
		job.setCloudResourceTypeName(SystemType.getSystemTypeByNo(advice.getCloudResourceType()).getCnName());
		job.setDstCloudResourceId(advice.getDstCloudResourceId());
		job.setDstDatacenterId(advice.getDstDatacenterId());
		job.setSrcDatacenterId(advice.getSrcDatacenterId());
		job.setInstanceId(advice.getInstanceId());
		job.setInstanceName(advice.getInstanceName());
		job.setSchedulerModel(advice.getSchedulerModel());
		job.setSchedulerModelTool(advice.getSchedulerModelTool());
		job.setSchedulerStrategyConfig(advice.getSchedulerStrategyConfig());
		job.setStatus(SchedulerJobStatus.READY.getValue());
		job.setAppName(advice.getAppName());
		job.setCloudResourceName(advice.getCloudResourceName());
		schedulerJobDao.save(job);
//		advice.setStatus(SchedulerAdviceStatus.HASSCH.getValue());
//		List<String> fieds = new ArrayList<>();
//		fieds.add("status");
		dao.updateStatusByInstanceId(SchedulerAdviceStatus.HASSCH.getValue(), advice.getInstanceId());
	}
	/**
	 * 根据迁移建议的状态，把迁移建议激活到job表去
	 */
	public void moveAdviceToJop() {
		Integer status = SchedulerAdviceStatus.TOSCH.getValue();
		List<SchedulerAdviceEntity> advices = listReadyAdvice(status);
		for(SchedulerAdviceEntity advice : advices) {
			SchedulerJobEntity job = new SchedulerJobEntity();
			job.setAppId(advice.getAppId());
			job.setId(UUID.randomUUID().toString());
			job.setBeginTime(new Date());
			job.setCloudResourceId(advice.getCloudResourceId());
			job.setCloudResourceTypeName(SystemType.getSystemTypeByNo(advice.getCloudResourceType()).getCnName());
			job.setDstCloudResourceId(advice.getDstCloudResourceId());
			job.setDstDatacenterId(advice.getDstDatacenterId());
			job.setSrcDatacenterId(advice.getSrcDatacenterId());
			job.setInstanceId(advice.getInstanceId());
			job.setInstanceName(advice.getInstanceName());
			job.setSchedulerModel(advice.getSchedulerModel());
			job.setSchedulerModelTool(advice.getSchedulerModelTool());
			job.setSchedulerStrategyConfig(advice.getSchedulerStrategyConfig());
			job.setStatus(SchedulerJobStatus.READY.getValue());
			job.setAppName(advice.getAppName());
			job.setCloudResourceName(advice.getCloudResourceName());
			schedulerJobDao.save(job);
//			advice.setStatus(SchedulerAdviceStatus.HASSCH.getValue());
//			List<String> fieds = new ArrayList<>();
//			fieds.add("status");
//			dao.update(advice, fieds);
			dao.updateStatusByInstanceId(SchedulerAdviceStatus.HASSCH.getValue(), advice.getInstanceId());
		}
	}

	public void deleteByAppId(String appId) {
		dao.deleteByAppId(appId);
		
	}
	public void deleteByReadyStatus(int model) {
		dao.deleteByReadyStatus(model);
	}
	public void deleteByInstanceId(String instanceId) {
		dao.deleteByInstanceId(instanceId);
		
	}
	
	public List<SchedulerAdviceEntity> listByAppId(String appId){
		return  dao.findByProperty("app_id", appId);
	}

	public List<DatacenterResourceVo> aviableDatacenter(AviableDatacenterMsg msg) {
		String datacenterId = msg.getDatacenterId();
		DatacenterEntity dataen = datacenterDao.getById(datacenterId);
		
		List<DatacenterResourceVo> vos = cloudResourceConfigDao.getAviableDatacenter(msg, dataen.getStructure());
				
		return vos;
	}

	public void startJob(StartJobMsg msg) {
		PageInstanceMsg pagemsg = new PageInstanceMsg();
		pagemsg.setInstanceId(msg.getInstanceId());
		PageResult<AppInstanceVo> page = appService.instancePage(pagemsg);
		if(page != null && page.getList() != null && page.getList().size() == 1) {
			AppInstanceVo vo = page.getList().get(0);
			SchedulerJobEntity job = new SchedulerJobEntity();
			job.setAppId(vo.getAppId());
			job.setId(UUID.randomUUID().toString());
			job.setBeginTime(new Date());
			job.setCloudResourceId(vo.getResourceId());
			job.setCloudResourceTypeName(SystemType.getSystemTypeByNo(vo.getType()).getCnName());
			job.setDstCloudResourceId(msg.getCloudResourceId());
			job.setDstDatacenterId(msg.getDatacenterId());
			job.setSrcDatacenterId(vo.getDatacenterId());
			job.setInstanceId(vo.getInstanceId());
			job.setInstanceName(vo.getInstanceName());
			job.setSchedulerModel(null);
			
			// 迁移工具选择
			int tool = 0;
			if (vo.getType().equals(SystemType.HUAWEI.getNo())) {
				tool = 2;
			} else if (vo.getType().equals(SystemType.ALI.getNo())) {
				tool = 1;
			}
//			int mode = 0;
//			List<DictModel> models = sysDictMapper.queryDictItemsByCode(DictCode.SCHEDULER_MODEL.getCode());
//			if (models != null) {
//				for (DictModel value : models) {
//					mode = Integer.parseInt(value.getValue());
//				}
//			}
			// 迁移配置
			int schConfig = 0;
			List<DictModel> configs = sysDictMapper.queryDictItemsByCode(DictCode.SCHEDULER_STRATEGY_CONFIG.getCode());
			if (configs != null) {
				for (DictModel value : configs) {
					schConfig = Integer.parseInt(value.getValue());
				}
			}
			job.setSchedulerModelTool(tool);
			job.setSchedulerStrategyConfig(schConfig);
			job.setStatus(SchedulerJobStatus.READY.getValue());
			job.setAppName(vo.getAppName());
			job.setCloudResourceName(vo.getResourceName());
			schedulerJobDao.save(job);
			
			//增加建议，建议状态为正在迁移
			SchedulerAdviceEntity advice = dao.findUniqueByProperty("instanceId", msg.getInstanceId());
			if(advice != null) {
				advice.setStatus(SchedulerAdviceStatus.HASSCH.getValue());
				List<String> fieds = new ArrayList<>();
				fieds.add("status");
				dao.update(advice, fieds);
			}else {
				advice = new SchedulerAdviceEntity();
				advice.setAppId(vo.getAppId());
				advice.setAppName(vo.getAppName());
				advice.setCloudResourceId(vo.getResourceId());
				advice.setCloudResourceName(vo.getResourceName());
				advice.setCloudResourceType(vo.getType());
				advice.setDstDatacenterId(msg.getDatacenterId());
				advice.setInstanceId(msg.getInstanceId());
				advice.setInstanceName(vo.getInstanceName());
				advice.setSrcDatacenterId(vo.getDatacenterId());
				advice.setCreateTime(new Date());
				advice.setSchedulerModelTool(tool);
				advice.setSchedulerModel(null);
				advice.setSchedulerStrategyConfig(schConfig);
				advice.setDstCloudResourceId(msg.getCloudResourceId());
				advice.setStatus(SchedulerAdviceStatus.HASSCH.getValue());
				dao.save(advice);
			}
		}
		
	}

	public SchedulerOverview overview() {
		//查询最近7天的
		String dateString = getPastDate(6);
		SchedulerOverview overview = schedulerJobDao.overview(dateString);
		return overview;
	}
	
	
	private String getPastDate(int past) {  
		Calendar calendar = Calendar.getInstance();  
		calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);  
		Date today = calendar.getTime();  
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
		String result = format.format(today);  
		return result;  
	 }   
}
